<?php

namespace App\Http\Controllers;

use App\Helpers\Utils;
use App\Models\Building;
use App\Models\Dorm;
use App\Models\DormType;
use Illuminate\Http\Request;
use Prettus\Validator\Exceptions\ValidatorException;
use App\Http\Requests\BuildingCreateRequest;
use App\Http\Requests\BuildingUpdateRequest;
use App\Repositories\BuildingRepository;
use App\Models\Company;

/**
 * Class BuildingsController.
 *
 * @package namespace App\Http\Controllers;
 */
class BuildingsController extends Controller
{
    /**
     * @var BuildingRepository
     */
    protected $repository;

    /**
     * BuildingsController constructor.
     *
     * @param BuildingRepository $repository
     * @param BuildingValidator $validator
     */
    public function __construct(BuildingRepository $repository)
    {
        $this->repository = $repository;
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $this->repository->pushCriteria(app('Prettus\Repository\Criteria\RequestCriteria'));
        if (\Route::currentRouteName() == 'api.buildings.index') {
            if ($request->has('company_id')) {
                //提供给dorm_app使用的接口数据
                if ($request->has('filter')) {
                    $buildings = $this->repository->where('company_id', request()->company_id)->orderBy('record_order')->get();
                } else {
                    $buildings = $this->repository->with('dorms:id,building_id,code,record_order')->where('company_id', request()->company_id)->orderBy('record_order')->get();
                }
            } else {
                if ($request->has('filter')) {
                    $buildings = $this->repository->orderBy('record_order')->get();
                } else {
                    $buildings = $this->repository->with('dorms:id,building_id,code,record_order')->orderBy('record_order')->get();
                }
            }
        } else {
            //index 页面动态表格数据
            $buildings = $this->repository->with(['company', 'dormType'])->all();
        }

        if (request()->wantsJson()) {

            return response()->json([
                'data' => $buildings,
            ]);
        }
        \request()->flash();
        return view('buildings.index', compact('buildings'));
    }

    public function create()
    {
        $dormTypes = DormType::all()->pluck('name', 'id');
        $companies = Company::all()->pluck('name', 'id');
        return view('buildings.create', compact('dormTypes', 'companies'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  BuildingCreateRequest $request
     *
     * @return \Illuminate\Http\Response
     *
     * @throws \Prettus\Validator\Exceptions\ValidatorException
     */
    public function store(BuildingCreateRequest $request)
    {
        try {

            $building = $this->repository->create($request->all());

            $response = [
                'message' => 'Building created.',
                'data'    => $building->toArray(),
            ];

            if ($request->wantsJson()) {

                return response()->json($response);
            }

            return redirect()->back()->with('message', $response['message']);
        } catch (ValidatorException $e) {
            if ($request->wantsJson()) {
                return response()->json([
                    'error'   => true,
                    'message' => $e->getMessageBag()
                ]);
            }

            return redirect()->back()->withErrors($e->getMessageBag())->withInput();
        }
    }

    /**
     * Display the specified resource.
     *
     * @param  int $id
     *
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $building = $this->repository->find($id);

        if (request()->wantsJson()) {

            return response()->json([
                'data' => $building,
            ]);
        }

        return view('buildings.show', compact('building'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int $id
     *
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $building = $this->repository->find($id);
        $dormTypes = DormType::all()->pluck('name', 'id');
        $companies = Company::all()->pluck('name', 'id');
        return view('buildings.edit', compact('building', 'dormTypes', 'companies'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  BuildingUpdateRequest $request
     * @param  string            $id
     *
     * @return Response
     *
     * @throws \Prettus\Validator\Exceptions\ValidatorException
     */
    public function update(BuildingUpdateRequest $request, $id)
    {
        try {

            $building = $this->repository->update($request->all(), $id);

            $response = [
                'message' => 'Building updated.',
                'data'    => $building->toArray(),
            ];

            if ($request->wantsJson()) {

                return response()->json($response);
            }

            return redirect()->back()->with('message', $response['message']);
        } catch (ValidatorException $e) {

            if ($request->wantsJson()) {

                return response()->json([
                    'error'   => true,
                    'message' => $e->getMessageBag()
                ]);
            }

            return redirect()->back()->withErrors($e->getMessageBag())->withInput();
        }
    }


    /**
     * Remove the specified resource from storage.
     *
     * @param  int $id
     *
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $deleted = $this->repository->delete($id);

        if (request()->wantsJson()) {

            return response()->json([
                'message' => 'Building deleted.',
                'deleted' => $deleted,
            ]);
        }

        return redirect()->back()->with('message', 'Building deleted.');
    }

    public function orderSort()
    {
        $buildings = Building::orderBy('record_order')->orderBy('short_name')->get();
        return view('buildings.sort', compact('buildings'));
    }

    public function orderSave(Request $request)
    {
        try {
            \DB::beginTransaction();
            $order = $request->get('order');
            foreach ($order as $o => $id) {
                $building = Building::find($id);
                $building->record_order = $o + 1;
                $building->save();
            }
            \DB::commit();
            if ($request->wantsJson()) {
                return response()->json([
                    'message' => 'Building record order saved.',
                    'saved' => true,
                ]);
            }
            return redirect()->back()->with('message', 'Building record order saved.');
        } catch (\Exception $exception) {
            \DB::rollBack();
            if ($request->wantsJson()) {
                return response()->json([
                    'error' => true,
                    'message' => 'Building record order saved failed:' . $exception->getMessage(),
                ]);
            }
            return redirect()->back()->withErrors($exception->getMessage());
        }
    }

    public function genDorms($id)
    {
        try {
            ini_set('max_execution_time', '300');
            $n = Utils::gen_dorms($id);
            if (\request()->wantsJson()) {
                return response()->json([
                    'message' => 'dorm generate success',
                    'generated' => $n
                ]);
            }
            return redirect()->back()->with('message', 'dorm generate success');
        } catch (\Exception $exception) {
            if (\request()->wantsJson()) {

                return response()->json([
                    'error'   => true,
                    'message' => $exception->getMessage()
                ]);
            }
            return redirect()->back()->withErrors($exception->getMessage());
        }
    }
}
